package cn.javacart.jfinal.php.render;

import java.io.ByteArrayOutputStream;
import java.io.File;
import java.io.FileInputStream;
import java.io.IOException;
import java.util.HashMap;
import java.util.Map;

import php.runtime.env.CompileScope;
import php.runtime.env.ConcurrentEnvironment;
import php.runtime.env.Context;
import php.runtime.env.Environment;
import php.runtime.reflection.ModuleEntity;

import com.jfinal.kit.LogKit;

/**
 * PHP环境
 * @author farmer
 *
 */
public class PhpEnvironment {

	/**
	 * PHP运行环境
	 */
	private Environment env = null;
	/**
	 * 输出流
	 */
	private ByteArrayOutputStream out = new ByteArrayOutputStream();
	/**
	 * 模板根路径
	 */
	private String basePath;
	/**
	 * 
	 */
	private Map<String, ModuleEntity> phpModuleEntityMap = new HashMap<String, ModuleEntity>();
	/**
	 * 
	 */
	private CompileScope scope;
	/**
	 * ENV ID
	 */
	private int envId;
	
	public PhpEnvironment(int envId, CompileScope scope, String basePath) {
		this.setEnv(new ConcurrentEnvironment(scope,out));
		this.setBasePath(basePath);
		this.setScope(scope);
		this.setEnvId(envId);
	}

	public Environment getEnv() {
		return env;
	}

	public void setEnv(Environment env) {
		this.env = env;
	}
	
	/**
	 * 取出内容作为数组
	 * @return
	 */
	public byte[] getContentAsArray(){
		byte[] content = out.toByteArray();
		out.reset();
		return content;
	}
	
	/**
	 * 取出内容
	 * @return
	 */
	public String getContent(){
		String content = new String(out.toByteArray(),env.getDefaultCharset());
		out.reset();
		return content;
	}

	public String getBasePath() {
		return basePath;
	}

	public void setBasePath(String basePath) {
		this.basePath = basePath;
	}

	/**
	 * 获取PHP模块
	 * @param view
	 * @return
	 */
	public ModuleEntity getModuleEntity(String view){
		File viewFile = new File(basePath, view);		//模板路径
		String key = view.concat(viewFile.lastModified()+"");
		ModuleEntity moduleEntity = phpModuleEntityMap.get(key);
		if(moduleEntity == null){
			long start = System.currentTimeMillis();
			FileInputStream in = null;
			try {
				in = new FileInputStream(viewFile);
				Context context = new Context(in, env.getDefaultCharset());
				/*
		        JvmCompiler compiler = new JvmCompiler(env, context);
		        moduleEntity =  compiler.compile(true);
		        scope.loadModule(moduleEntity,true);
		        */
				moduleEntity = env.importModule(context);
		        phpModuleEntityMap.put(key, moduleEntity);
			} catch (Throwable e) {
				LogKit.error("PHP模板异常！",e);
				throw new PhpCompilException("PHP模板异常！",e);
			}finally{
				if(in != null){
					try {
						in.close();
					} catch (IOException e) { e.printStackTrace(); }
				}
			}
			long end = System.currentTimeMillis();
			LogKit.info("ENV ID:"+getEnvId()+","+view+"编译耗时:"+(end-start)+"毫秒.");
		}
		return moduleEntity;
	}

	public CompileScope getScope() {
		return scope;
	}

	public void setScope(CompileScope scope) {
		this.scope = scope;
	}

	public int getEnvId() {
		return envId;
	}

	public void setEnvId(int envId) {
		this.envId = envId;
	}
	
}
